package es.castorm.arch.logging;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class TraceLoggingAspect {

	public static final Logger logger = LoggerFactory.getLogger(TraceLoggingAspect.class);

	@Around("within(@es.castorm.arch.logging.Logged *) || within(@(@es.castorm.arch.logging.Logged *) *)")
	public Object logAround(ProceedingJoinPoint jp) throws Throwable {

		Class<?> clazz = jp.getTarget().getClass();
		String clazzName = clazz.getName();
		String methodName = jp.getSignature().getName();
		Logger logger = LoggerFactory.getLogger(clazz);

		Object result = null;
		try {
			logger.trace("> {}.{}()", clazzName, methodName);
			result = jp.proceed();
			logger.trace("< {}.{}()", clazzName, methodName);
		} catch (Throwable t) {
			if (t.getMessage() != null) {
				logger.trace("X {}.{}(): {}", clazzName, methodName, t.getMessage());
			} else {
				logger.trace("X {}.{}()", clazzName, methodName);
			}
			throw t;
		}

		return result;
	}
}
